package com.casa.POI.dianping;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;

public class FetchCitiesExecutor extends Executor {
	
	@Override
	public void execute() {
		if (!isCitiesPersisted()) {
			List<City> cities = null;
			try {
				while (cities == null || cities.size() == 0) {
					TagNode html = fetchCityListPage();
					cities = extractCities(html);
				}
				persistCities(cities);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private boolean isCitiesPersisted() {
		Session s = SessionManager.getInstance().openSession();
		Criteria c = s.createCriteria(City.class);
		c.setMaxResults(1);
		City city = (City) c.uniqueResult();
		s.close();
		return city != null;
	}

	private void persistCities(List<City> cities) {
		Session s = SessionManager.getInstance().openSession();
		s.beginTransaction();
		for (City city : cities) {
			s.saveOrUpdate(city);
		}
		s.getTransaction().commit();
		s.close();
	}

	private List<City> extractCities(TagNode html) throws XPatherException {
		Object[] results = html.evaluateXPath("/body/script");
		
		List<City> cities = new ArrayList<City>();
		for (Object result : results) {
			TagNode scriptNode = (TagNode) result;
			String text = scriptNode.getText().toString();
//			Console.newLineWriteLine(text);
			if (text.contains("citySelector_cityList")) {
				Pattern p = Pattern.compile("'(.+?)\\|(.+?)\\|(.+?)\\|(\\d+?)\\|(.+?)'");
				Matcher m = p.matcher(text);
				while (m.find()) {
					String name = m.group(1);
					String pinyin = m.group(2);
					String id = m.group(4);
					String url = m.group(5);
					if (isValidCity(url)) {
						City city = new City(Integer.parseInt(id), name, pinyin);
						cities.add(city);
						printStatus(String.format("%s:%s", id, pinyin));
					}
				}
				break;
			}
		}
		return cities;
	}

	private boolean isValidCity(String url) {
		return !url.contains("category") && !url.contains("more") && !url.contains("guowai");
	}

	private TagNode fetchCityListPage() throws IOException {
		while (true) {
			try {
				return SpiderUtil.cleanUrl("/citylist");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new FetchCitiesExecutor().execute();
	}

}
